package com.rickpan.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ配置类
 * 配置团队聊天室消息队列的Exchange、Queue和绑定关系
 *
 * @author 开发团队协调员
 * @since 2025-07-17
 */
@Configuration
@ConditionalOnProperty(name = "spring.rabbitmq.host", matchIfMissing = false)
public class RabbitMQConfig {

    // ==================== Exchange定义 ====================
    
    /**
     * 团队消息直接路由Exchange
     * 用于团队消息的精确路由
     */
    @Bean
    public DirectExchange teamDirectExchange() {
        return ExchangeBuilder
                .directExchange("team.direct")
                .durable(true)
                .build();
    }
    
    /**
     * 团队广播Exchange
     * 用于系统通知等广播消息
     */
    @Bean
    public FanoutExchange teamFanoutExchange() {
        return ExchangeBuilder
                .fanoutExchange("team.fanout")
                .durable(true)
                .build();
    }
    
    /**
     * 团队主题路由Exchange
     * 用于基于消息类型的路由
     */
    @Bean
    public TopicExchange teamTopicExchange() {
        return ExchangeBuilder
                .topicExchange("team.topic")
                .durable(true)
                .build();
    }
    
    // ==================== 死信Exchange和Queue ====================
    
    /**
     * 死信Exchange
     * 处理失败的消息
     */
    @Bean
    public DirectExchange deadLetterExchange() {
        return ExchangeBuilder
                .directExchange("team.dlx")
                .durable(true)
                .build();
    }
    
    /**
     * 死信队列
     * 存储处理失败的消息
     */
    @Bean
    public Queue deadLetterQueue() {
        return QueueBuilder
                .durable("message.dlq")
                .build();
    }
    
    /**
     * 死信队列绑定
     */
    @Bean
    public Binding deadLetterBinding() {
        return BindingBuilder
                .bind(deadLetterQueue())
                .to(deadLetterExchange())
                .with("dlq");
    }
    
    // ==================== 通用队列 ====================
    
    /**
     * 文件上传进度队列
     * 处理文件上传进度消息
     */
    @Bean
    public Queue fileUploadProgressQueue() {
        return QueueBuilder
                .durable("file.upload.progress")
                .withArgument("x-dead-letter-exchange", "team.dlx")
                .withArgument("x-dead-letter-routing-key", "dlq")
                .withArgument("x-message-ttl", 300000) // 5分钟TTL
                .build();
    }
    
    /**
     * 系统广播队列
     * 处理系统级广播消息
     */
    @Bean
    public Queue systemBroadcastQueue() {
        return QueueBuilder
                .durable("system.broadcast")
                .withArgument("x-dead-letter-exchange", "team.dlx")
                .withArgument("x-dead-letter-routing-key", "dlq")
                .build();
    }
    
    /**
     * 系统广播队列绑定到Fanout Exchange
     */
    @Bean
    public Binding systemBroadcastBinding() {
        return BindingBuilder
                .bind(systemBroadcastQueue())
                .to(teamFanoutExchange());
    }
    
    // ==================== 消息转换器和模板配置 ====================
    
    /**
     * JSON消息转换器
     * 将消息对象转换为JSON格式
     */
    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }
    
    /**
     * RabbitTemplate配置
     * 配置消息发送模板
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(messageConverter());
        
        // 启用发送确认
        template.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                System.out.println("✅ 消息发送成功: " + correlationData);
            } else {
                System.err.println("❌ 消息发送失败: " + cause);
            }
        });
        
        // 启用消息返回
        template.setReturnsCallback(returned -> {
            System.err.println("❌ 消息被退回: " + returned.getMessage() + 
                             ", 路由键: " + returned.getRoutingKey() + 
                             ", 原因: " + returned.getReplyText());
        });
        
        return template;
    }

    /**
     * RabbitAdmin配置
     * 用于动态创建和管理队列、Exchange和绑定
     */
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }

    /**
     * 消息监听器容器工厂配置
     */
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(messageConverter());
        
        // 设置并发消费者数量
        factory.setConcurrentConsumers(1);
        factory.setMaxConcurrentConsumers(5);
        
        // 设置预取数量
        factory.setPrefetchCount(10);
        
        return factory;
    }
    
    // ==================== 动态队列创建方法 ====================
    
    /**
     * 创建团队消息队列
     * 根据团队ID动态创建队列
     * 
     * @param teamId 团队ID
     * @return 团队消息队列
     */
    public static Queue createTeamMessageQueue(Long teamId) {
        return QueueBuilder
                .durable("team.message." + teamId)
                .withArgument("x-dead-letter-exchange", "team.dlx")
                .withArgument("x-dead-letter-routing-key", "dlq")
                .withArgument("x-message-ttl", 86400000) // 24小时TTL
                .build();
    }
    
    /**
     * 创建用户通知队列
     * 根据用户ID动态创建队列
     * 
     * @param userId 用户ID
     * @return 用户通知队列
     */
    public static Queue createUserNotificationQueue(Long userId) {
        return QueueBuilder
                .durable("user.notification." + userId)
                .withArgument("x-dead-letter-exchange", "team.dlx")
                .withArgument("x-dead-letter-routing-key", "dlq")
                .withArgument("x-message-ttl", 3600000) // 1小时TTL
                .build();
    }
    
    /**
     * 创建团队消息队列绑定
     * 
     * @param teamId 团队ID
     * @param queue 队列
     * @param exchange Exchange
     * @return 绑定关系
     */
    public static Binding createTeamMessageBinding(Long teamId, Queue queue, DirectExchange exchange) {
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("team." + teamId + ".message");
    }
}
